package com.rongmei.jdsync.dto.sync;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 重试结果统计
 *
 * @author dongjun
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(description = "重试结果统计")
public class RetryResult {

    @Schema(description = "总重试数量", example = "10")
    private int totalRetryCount;

    @Schema(description = "重试成功数量", example = "8")
    private int retrySuccessCount;

    @Schema(description = "重试失败数量", example = "2")
    private int retryFailedCount;

    @Schema(description = "重试开始时间")
    private LocalDateTime startTime;

    @Schema(description = "重试结束时间")
    private LocalDateTime endTime;

    @Schema(description = "重试耗时（毫秒）")
    private long duration;

    @Schema(description = "重试的批次ID列表")
    private List<String> retryBatchIds;

    @Schema(description = "重试状态：SUCCESS-全部成功，PARTIAL-部分成功，FAILED-全部失败，NO_RETRY-无需重试")
    private RetryStatus status;

    @Schema(description = "错误信息")
    private String errorMessage;

    /**
     * 重试状态枚举
     */
    public enum RetryStatus {
        SUCCESS,    // 全部成功
        PARTIAL,    // 部分成功
        FAILED,     // 全部失败
        NO_RETRY    // 无需重试
    }

    /**
     * 创建无需重试的结果
     */
    public static RetryResult noRetry() {
        return RetryResult.builder()
                .totalRetryCount(0)
                .retrySuccessCount(0)
                .retryFailedCount(0)
                .status(RetryStatus.NO_RETRY)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 创建成功重试结果
     */
    public static RetryResult success(int totalCount) {
        return RetryResult.builder()
                .totalRetryCount(totalCount)
                .retrySuccessCount(totalCount)
                .retryFailedCount(0)
                .status(RetryStatus.SUCCESS)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 创建失败重试结果
     */
    public static RetryResult failure(int totalCount, String errorMessage) {
        return RetryResult.builder()
                .totalRetryCount(totalCount)
                .retrySuccessCount(0)
                .retryFailedCount(totalCount)
                .status(RetryStatus.FAILED)
                .errorMessage(errorMessage)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 创建部分成功重试结果
     */
    public static RetryResult partial(int totalCount, int successCount, int failedCount) {
        return RetryResult.builder()
                .totalRetryCount(totalCount)
                .retrySuccessCount(successCount)
                .retryFailedCount(failedCount)
                .status(RetryStatus.PARTIAL)
                .endTime(LocalDateTime.now())
                .build();
    }

    /**
     * 计算重试成功率
     */
    public double getRetrySuccessRate() {
        if (totalRetryCount == 0) return 1.0;
        return (double) retrySuccessCount / totalRetryCount;
    }

    /**
     * 是否全部重试成功
     */
    public boolean isAllRetrySuccess() {
        return totalRetryCount > 0 && retryFailedCount == 0;
    }

    /**
     * 是否全部重试失败
     */
    public boolean isAllRetryFailed() {
        return totalRetryCount > 0 && retrySuccessCount == 0;
    }

    /**
     * 是否部分重试成功
     */
    public boolean isPartialRetrySuccess() {
        return retrySuccessCount > 0 && retryFailedCount > 0;
    }

    /**
     * 设置重试开始时间
     */
    public RetryResult markStart() {
        this.startTime = LocalDateTime.now();
        return this;
    }

    /**
     * 设置重试结束时间并计算耗时
     */
    public RetryResult markEnd() {
        this.endTime = LocalDateTime.now();
        if (this.startTime != null) {
            this.duration = java.time.Duration.between(startTime, endTime).toMillis();
        }
        return this;
    }

    @Override
    public String toString() {
        return String.format("RetryResult{总重试=%d, 成功=%d, 失败=%d, 成功率=%.2f%%, 状态=%s, 耗时=%dms}", 
                totalRetryCount, retrySuccessCount, retryFailedCount, 
                getRetrySuccessRate() * 100, status, duration);
    }
}
